import TableExpression from "../expression/TableExpression";
import UnchangedExpression from "../expression/impl/UnchangedExpression";
import MysqlCore from "./MysqlCore";
import HeavyLoad from "../utils/HeavyLoad";
import CoreExpression from "../expression/abstract/CoreExpression";
import Factory from "./Factory";
import MetaData from "src/expression/MetaData";

/***
 * 表查询构造器
 */
class TableQueryBuilder {
    protected meta?:MetaData;
    constructor(meta?:MetaData) {
        this.meta = meta;
    }

    static {
        Factory.TableQueryBuilder = TableQueryBuilder;
    }

    /**
     * 选择需要操作的表
     */
    public table(name: ((table: TableQueryBuilder) => any), alias: string): TableExpression;
    public table(name: string | ((table: TableQueryBuilder) => any), alias?: string): TableExpression;
    public table(name: string | ((table: TableQueryBuilder) => any), alias: string = '') {
        // 在这里进行子查询操作
        return HeavyLoad.build<TableExpression>()
            .method((name: string, alias?: string)=>{
                // 正常查询
                return new TableExpression(name as string, alias,this.meta as any)
            },["string","string"])
            .method((name: ((table: TableQueryBuilder) => any), alias: string)=>{
                // 子查询
                let meta = new Factory.MetaData(this.meta?.core as MysqlCore,this.meta?.sqlFieldRule,this.meta?.codeFieldRule)
                meta.isSubquery = true;
                let build = new TableQueryBuilder(meta);
                name(build);
                if(!meta.status){
                    // 手动调用get
                    CoreExpression.prototype.get.bind({metadata:meta})();
                }
                if(this.meta?.table instanceof TableExpression){
                    meta.add(new UnchangedExpression(",(",meta),0);
                }else{
                    meta.add(new UnchangedExpression("(",meta),0);
                }
                meta.add(new UnchangedExpression(")",meta));
                this.meta?.parameter.push(...meta.parameter)
                return new TableExpression(new UnchangedExpression(meta.toSql() as string,this.meta as MetaData), alias,this.meta as MetaData)
            },["function","string"]).run(name,alias)
    }

    public select(sql: string, parameter: any[] = []) {
        // @ts-ignore
        this.meta.parameter = parameter;
        // @ts-ignore
        this.meta.add(new UnchangedExpression(sql,this.meta))
        return this.meta?.core?.select(this.meta as MetaData);
    }
}
export  =  TableQueryBuilder;